﻿using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Configuration;
using KS.DataWrapper.Interface;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Driver.Linq;
using Newtonsoft.Json;

namespace KS.DataWrapper.Mongo
{
    public class MongoDBHelper
    {
        public static MongoDatabase CreateDB()
        {
            string connection = Connection = WebConfigurationManager.AppSettings["MongoDBConnection"];
            string dbName = DataBase = WebConfigurationManager.AppSettings["MongoDBDataBase"];
            ConnectionForClient = WebConfigurationManager.AppSettings["MongoDBConnectionForClient"];

            MongoClient client = new MongoClient(connection); // connect to localhost
            MongoServer server = client.GetServer();
            return server.GetDatabase(dbName);
        }

        public static MongoDatabase CreateDBNoCredentials(string uri, string dbName)
        {
            //string connection = Connection = WebConfigurationManager.AppSettings["MongoDBConnection"];
            //string dbName = DataBase = WebConfigurationManager.AppSettings["MongoDBDataBase"];
            //ConnectionForClient = WebConfigurationManager.AppSettings["MongoDBConnectionForClient"];

            MongoClient client = new MongoClient(new MongoUrl(uri)); // connect to localhost
            MongoServer server = client.GetServer();
            return server.GetDatabase(dbName);
        }

        //public static MongoDatabase CreateDB(bool userPassword)
        //{
        //    string connection = Connection = WebConfigurationManager.AppSettings["MongoDBConnection"];
        //    string dbName = DataBase = WebConfigurationManager.AppSettings["MongoDBDataBase"];
        //    string login = WebConfigurationManager.AppSettings["MongoDBLogin"];
        //    string password = WebConfigurationManager.AppSettings["MongoDBPassword"];
        //    ConnectionForClient = WebConfigurationManager.AppSettings["MongoDBConnectionForClient"];
        //    return CreateDB(connection, dbName, login, password);
        //}

        //public static MongoDatabase CreateDB(string mongoDBConnection, string mongoDBDataBase)
        //{
        //    string connection = Connection =  mongoDBConnection;
        //    string dbName = DataBase = mongoDBDataBase;

        //    MongoClient client = new MongoClient(new MongoUrl(connection)); // connect to localhost
        //    MongoServer server = client.GetServer();
        //    //MongoCredentials credentials = new MongoCredentials("username", "password");
        //    //MongoDatabase salaries = server.GetDatabase("salaries", credentials);
        //    return server.GetDatabase(dbName);
        //}

        public static MongoDatabase CreateClientDB(string mongoDBConnection, string dataBaseName, string login, string password)
        {
            //string connection = Connection = mongoDBConnection;
            //string dbName = DataBase = mongoDBDataBase;

            //var credential = MongoCredential.CreateMongoCRCredential(mongoDBDataBase, login, password);
            //var settings = new MongoClientSettings
            //{
            //    Credentials = new[] { credential },
            //    Server = new MongoServerAddress()
            //};

            if (string.IsNullOrEmpty(login)&&string.IsNullOrEmpty(password))
            {
                return CreateDBNoCredentials(mongoDBConnection, dataBaseName);
            }
            else
            {
                string ssss = string.Format(mongoDBConnection, login, password);
                MongoClient client = new MongoClient(ssss);
                MongoServer server = client.GetServer();

                return server.GetDatabase(dataBaseName);
            }
            
        }

        private static MongoDatabase PrivateMongoDatabase { get; set; }

        #region 
        

        public static IQueryable<T> GetCollection<T>(MongoDatabase db)
        {
            return db.GetCollection(typeof(T).Name).AsQueryable<T>();
        }

        public static IQueryable<T> GetCollection<T>()
        {
            return GetCollection<T>(PrivateMongoDatabase);
        }

        public static bool Add<T>(MongoDatabase db, IDataClass item )
        {
            if (item == null)
            {
                return false;
            }

            var collection = db.GetCollection<T>(typeof(T).Name);

            if (item.ID == ObjectId.Empty.ToString())
            {
                item.ID = ObjectId.GenerateNewId().ToString();
            }
            item.Vts = System.DateTime.UtcNow;
            var result = collection.Insert(item);
            return result.Ok;

        }

        public static bool Add<T>(IDataClass item)
        {
            return Add<T>(PrivateMongoDatabase, item);
        }

        public static bool Save<T>( MongoDatabase db, IDataClass item)
        {
            if (item == null)
            {
                return false;
            }
            var collection = db.GetCollection<T>(typeof(T).Name);
            item.Vts = System.DateTime.UtcNow;
            var result = collection.Save(item);
            return result.Ok;
        }

        public static bool Save<T>(IDataClass item)
        {
            return Save<T>(PrivateMongoDatabase, item);
        }

        public static bool Delete<T>(MongoDatabase db, IDataClass item)
        {
            if (item == null)
            {
                return false;
            }
            var collection = db.GetCollection<T>(typeof(T).Name);
            IMongoQuery query = Query.EQ("ID", item.ID);
            SafeModeResult result = collection.Remove(query);
            return result.DocumentsAffected == 1;
        }

        public static bool Delete<T>(IDataClass item)
        {
            return Delete<T>(PrivateMongoDatabase, item);
        }

#endregion

        #region

        public static void CreateUser(MongoDatabase db, string userName, string password)
        {
            try
            {
                string updateScript = " db.addUser( { user: \"" + userName + "\", pwd: \"" + password + "\",  roles: [ \"read\" ] } )";
                var updateResult = db.Eval(updateScript).ToString(); 
            }
            catch {}
           
        }

        public static void CreateUser(string userName, string password)
        {
            var user = new MongoUser(userName,password,false);
            PrivateMongoDatabase.AddUser(user);
        }

        public static void RemoveUser(string userName)
        {
            PrivateMongoDatabase.RemoveUser(userName);
        }

        #endregion


        #region Property
        public static string Connection { get; set; }
        public static string DataBase { get; set; }

        public static string ConnectionForClient { get; set; }
        #endregion
        public static void GetCredentials(string server, string cookies)
        {
            WebClient wc = new WebClient();
            //TODO добавть куки
            string responce = wc.DownloadString(string.Format("{0}/{1}/KSAuth", server, KS.DataWrapper.Config.WebApiConfig.BaseUrl));
            var user = JsonConvert.DeserializeObject<KSUser>(responce);
            PrivateMongoDatabase = CreateClientDB(user.Connection, user.DataBase, user.Login, user.Password);

        }
    }
}